package utils.avia;

import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorBigInt;
import com.googlecode.aviator.runtime.type.AviatorBoolean;
import com.googlecode.aviator.runtime.type.AviatorObject;

import java.util.HashMap;
import java.util.Map;

/**
 * @author dan shouyang
 */
public class AviatorSimpleExample {
    static {
        AviatorEvaluator.addFunction(new MinFunction());
        AviatorEvaluator.addFunction(new EqualsFunction());
        AviatorEvaluator.addFunction(new NotEqualsFunction());
    }

    public static void main(String[] args) {
        test3();
    }

    static void test1() {
        String expression = "min(a,b)";
        Expression compiledExp = AviatorEvaluator.compile(expression, true);
        Map<String, Object> env = new HashMap<>();
        env.put("a", 100.3);
        env.put("b", 45);
        Double result = (Double) compiledExp.execute(env);
        System.out.println(result);
    }

    static void test2() {
        String expression = "eq(STATUS, \"lisi\")";
        Expression compiledExp = AviatorEvaluator.compile(expression, true);
        Map<String, Object> env = new HashMap<>();
        env.put("NAME", "zhangsan");
//        env.put("STATUS", -1000);
        env.put("STATUS", "lisi");
        Boolean matched = (Boolean) compiledExp.execute(env);
        System.out.println(matched);
    }

    static void test3() {
        String expression = "eq(STATUS, -1000) && neq(type, 1)";
        Expression compiledExp = AviatorEvaluator.compile(expression, true);
        Map<String, Object> env = new HashMap<>();
        env.put("NAME", "zhangsan");
        env.put("type", 2);
        env.put("STATUS", -1000);
        Boolean matched = (Boolean) compiledExp.execute(env);
        System.out.println(matched);
    }

    static class MinFunction extends AbstractFunction {
        @Override
        public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
            Number left = FunctionUtils.getNumberValue(arg1, env);
            Number right = FunctionUtils.getNumberValue(arg2, env);
            return new AviatorBigInt(Math.min(left.doubleValue(), right.doubleValue()));
        }

        @Override
        public String getName() {
            return "min";
        }
    }

    public static class EqualsFunction extends AbstractFunction {
        @Override
        public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
            String left = String.valueOf(arg1.getValue(env));
            String right = String.valueOf(arg2.getValue(env));
            return AviatorBoolean.valueOf(left.equals(right));
        }

        @Override
        public String getName() {
            return "eq";
        }
    }

    public static class NotEqualsFunction extends AbstractFunction {
        @Override
        public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
            String left = String.valueOf(arg1.getValue(env));
            String right = String.valueOf(arg2.getValue(env));
            return AviatorBoolean.valueOf(!left.equals(right));
        }

        @Override
        public String getName() {
            return "neq";
        }
    }
}